import facade.FarmingSystemFacade;
import java.util.Scanner;

public class Main {
    private static FarmingSystemFacade system;
    private static Scanner scanner;
    
    public static void main(String[] args) {
        System.out.println("=== 智能无人驾驶农机系统启动 ===\n");
        System.out.println("欢迎来到智能农机系统演示！本系统采用多种设计模式实现:");
        System.out.println("1. 工厂方法模式：创建不同类型的农机设备");
        System.out.println("2. 策略模式：实现不同环境下的路径规划算法");
        System.out.println("3. 观察者模式：环境监测器与农机设备间的通信");
        System.out.println("4. 状态模式：管理农机的各种工作状态");
        System.out.println("5. 责任链模式：处理系统异常和安全事件");
        System.out.println("6. 外观模式：提供统一的系统接口");
        System.out.println("7. 装饰器模式：动态为农机添加新功能\n");
        
        // 初始化系统和输入
        system = new FarmingSystemFacade();
        scanner = new Scanner(System.in);
        
        // 系统初始化
        System.out.println("\n正在初始化系统...");
        system.startSystem();
        
        // 显示主菜单
        boolean running = true;
        while(running) {
            displayMainMenu();
            int choice = getUserChoice(0, 8);
            
            switch(choice) {
                case 1:
                    monitorEnvironment();
                    break;
                case 2:
                    manageMachinery();
                    break;
                case 3:
                    taskManagement();
                    break;
                case 4:
                    pathPlanning();
                    break;
                case 5:
                    securityManagement();
                    break;
                case 6:
                    upgradeManagement(); // 新增装饰器功能管理
                    break;
                case 7:
                    runSimulation();
                    break;
                case 8:
                    systemStatus();
                    break;
                case 0:
                    running = false;
                    break;
            }
        }
        
        // 关闭资源
        scanner.close();
        System.out.println("\n=== 智能无人驾驶农机系统关闭 ===");
    }
    
    private static void displayMainMenu() {
        System.out.println("\n-------- 智能农机系统主菜单 --------");
        System.out.println("1. 环境监测管理 (观察者模式)");
        System.out.println("2. 农机设备管理 (工厂方法+状态模式)");
        System.out.println("3. 任务分配管理");
        System.out.println("4. 路径规划管理 (策略模式)");
        System.out.println("5. 安全系统管理 (责任链模式)");
        System.out.println("6. 设备升级管理 (装饰器模式)");
        System.out.println("7. 运行完整模拟");
        System.out.println("8. 查看系统状态");
        System.out.println("0. 退出系统");
        System.out.print("请选择操作 (0-8): ");
    }
    
    private static int getUserChoice(int min, int max) {
        int choice = -1;
        while (choice < min || choice > max) {
            try {
                String input = scanner.nextLine().trim();
                // 如果输入为空，继续等待有效输入
                if (input.isEmpty()) {
                    System.out.print("请输入有效数字 (" + min + "-" + max + "): ");
                    continue;
                }
                choice = Integer.parseInt(input);
                if (choice < min || choice > max) {
                    System.out.print("输入无效，请重新输入 (" + min + "-" + max + "): ");
                }
            } catch (NumberFormatException e) {
                System.out.print("请输入有效数字 (" + min + "-" + max + "): ");
            }
        }
        return choice;
    }
    
    // 获取一个整数输入，确保正确处理用户输入
    private static int getIntInput(int min, int max, String prompt) {
        System.out.print(prompt);
        return getUserChoice(min, max);
    }
    
    private static void monitorEnvironment() {
        boolean submenu = true;
        System.out.println("\n【设计模式应用】观察者模式：环境监测器作为被观察者，农机设备作为观察者");
        System.out.println("  - 当环境数据变化时，环境监测器会通知所有注册的农机设备");
        System.out.println("  - 农机设备根据收到的环境数据调整工作状态和参数");
        pause();
        
        while (submenu) {
            System.out.println("\n-------- 环境监测管理 --------");
            System.out.println("1. 更新土壤湿度");
            System.out.println("2. 更新气温");
            System.out.println("3. 更新风速");
            System.out.println("0. 返回主菜单");
            System.out.print("请选择操作 (0-3): ");
            
            int choice = getUserChoice(0, 3);
            switch (choice) {
                case 1:
                    int moisture = getIntInput(0, 100, "请输入新的土壤湿度 (0-100%): ");
                    system.updateSoilMoisture(moisture);
                    pause();
                    break;
                case 2:
                    int temperature = getIntInput(-20, 50, "请输入新的气温 (-20-50°C): ");
                    system.updateTemperature(temperature);
                    pause();
                    break;
                case 3:
                    int windSpeed = getIntInput(0, 30, "请输入新的风速 (0-30m/s): ");
                    system.updateWindSpeed(windSpeed);
                    pause();
                    break;
                case 0:
                    submenu = false;
                    break;
            }
        }
    }
    
    private static void manageMachinery() {
        boolean submenu = true;
        System.out.println("\n【设计模式应用】工厂方法模式：通过不同的工厂创建不同类型的农机");
        System.out.println("  - TractorFactory创建拖拉机");
        System.out.println("  - SeederFactory创建播种机");
        System.out.println("  - HarvesterFactory创建收割机");
        System.out.println("\n【设计模式应用】状态模式：农机设备可以在不同状态间切换");
        System.out.println("  - 空闲状态(IdleState)：设备待命");
        System.out.println("  - 工作状态(WorkingState)：执行任务");
        System.out.println("  - 故障状态(MalfunctionState)：需要维修");
        pause();
        
        while (submenu) {
            System.out.println("\n-------- 农机设备管理 --------");
            System.out.println("1. 查看所有设备");
            System.out.println("2. 查看设备详情");
            System.out.println("3. 手动更改设备状态");
            System.out.println("0. 返回主菜单");
            System.out.print("请选择操作 (0-3): ");
            
            int choice = getUserChoice(0, 3);
            switch (choice) {
                case 1:
                    system.listAllMachineries();
                    pause();
                    break;
                case 2:
                    int id = getIntInput(0, 2, "请输入设备ID (0-2): ");
                    system.showMachineryDetails(id);
                    pause();
                    break;
                case 3:
                    int machineId = getIntInput(0, 2, "请输入设备ID (0-2): ");
                    System.out.println("1. 设置为空闲状态");
                    System.out.println("2. 设置为工作状态");
                    System.out.println("3. 设置为故障状态");
                    int stateChoice = getIntInput(1, 3, "请选择新状态 (1-3): ");
                    system.changeMachineryState(machineId, stateChoice);
                    pause();
                    break;
                case 0:
                    submenu = false;
                    break;
            }
        }
    }
    
    private static void taskManagement() {
        boolean submenu = true;
        while (submenu) {
            System.out.println("\n-------- 任务分配管理 --------");
            System.out.println("1. 创建新任务");
            System.out.println("2. 查看所有任务");
            System.out.println("3. 完成指定任务");
            System.out.println("4. 取消指定任务");
            System.out.println("0. 返回主菜单");
            System.out.print("请选择操作 (0-4): ");
            
            int choice = getUserChoice(0, 4);
            switch (choice) {
                case 1:
                    System.out.println("可选任务类型:");
                    System.out.println("1. 耕地任务");
                    System.out.println("2. 播种任务");
                    System.out.println("3. 收割任务");
                    int taskType = getIntInput(1, 3, "请选择任务类型 (1-3): ");
                    
                    int machineId = getIntInput(0, 2, "请选择农机设备ID (0-2): ");
                    
                    String taskName = "";
                    switch (taskType) {
                        case 1: taskName = "耕地任务"; break;
                        case 2: taskName = "播种任务"; break;
                        case 3: taskName = "收割任务"; break;
                    }
                    
                    system.createTask(taskName, machineId);
                    pause();
                    break;
                case 2:
                    system.listAllTasks();
                    pause();
                    break;
                case 3:
                    int completeId = getIntInput(0, 10, "请输入要完成的任务ID: ");
                    system.completeTask(completeId);
                    pause();
                    break;
                case 4:
                    int cancelId = getIntInput(0, 10, "请输入要取消的任务ID: ");
                    System.out.print("请输入取消原因: ");
                    String reason = scanner.nextLine();
                    system.cancelTask(cancelId, reason);
                    pause();
                    break;
                case 0:
                    submenu = false;
                    break;
            }
        }
    }
    
    private static void pathPlanning() {
        boolean submenu = true;
        System.out.println("\n【设计模式应用】策略模式：动态切换路径规划算法");
        System.out.println("  - StandardPathStrategy：标准路径规划策略");
        System.out.println("  - EmergencyPathStrategy：紧急情况路径规划策略");
        pause();
        
        while (submenu) {
            System.out.println("\n-------- 路径规划管理 --------");
            System.out.println("1. 使用标准路径规划");
            System.out.println("2. 使用紧急路径规划");
            System.out.println("3. 自定义路径规划");
            System.out.println("0. 返回主菜单");
            System.out.print("请选择操作 (0-3): ");
            
            int choice = getUserChoice(0, 3);
            switch (choice) {
                case 1:
                    int stdMachineId = getIntInput(0, 2, "为哪个设备规划路径? (0-2): ");
                    System.out.print("输入任务描述: ");
                    String stdTask = scanner.nextLine();
                    system.useStandardPathPlanning(stdMachineId, stdTask);
                    pause();
                    break;
                case 2:
                    int emergencyMachineId = getIntInput(0, 2, "为哪个设备规划紧急路径? (0-2): ");
                    System.out.print("输入紧急情况描述: ");
                    String emergencyTask = scanner.nextLine();
                    system.useEmergencyPathPlanning(emergencyMachineId, emergencyTask);
                    pause();
                    break;
                case 3:
                    System.out.println("此功能尚未实现");
                    pause();
                    break;
                case 0:
                    submenu = false;
                    break;
            }
        }
    }
    
    private static void securityManagement() {
        boolean submenu = true;
        System.out.println("\n【设计模式应用】责任链模式：处理不同类型的安全事件");
        System.out.println("  - ObstacleHandler：处理障碍物事件");
        System.out.println("  - FaultDetectionHandler：处理设备故障事件");
        System.out.println("  - BoundaryCheckHandler：处理边界越界事件");
        System.out.println("  - 安全事件会按责任链传递，直到被合适的处理器处理");
        pause();
        
        while (submenu) {
            System.out.println("\n-------- 安全系统管理 --------");
            System.out.println("1. 模拟障碍物检测");
            System.out.println("2. 模拟设备故障");
            System.out.println("3. 模拟边界越界");
            System.out.println("0. 返回主菜单");
            System.out.print("请选择操作 (0-3): ");
            
            int choice = getUserChoice(0, 3);
            switch (choice) {
                case 1:
                    system.handleSecurityEvent("障碍物");
                    pause();
                    break;
                case 2:
                    system.handleSecurityEvent("设备故障");
                    pause();
                    break;
                case 3:
                    system.handleSecurityEvent("边界越界");
                    pause();
                    break;
                case 0:
                    submenu = false;
                    break;
            }
        }
    }
    
    private static void upgradeManagement() {
        boolean submenu = true;
        System.out.println("\n【设计模式应用】装饰器模式：动态为农机设备添加新功能");
        System.out.println("  - PrecisionGuidanceDecorator：添加精准导航功能");
        System.out.println("  - AutoIrrigationDecorator：添加自动灌溉功能");
        System.out.println("  - 装饰器可以在不修改原有类的情况下，动态扩展对象功能");
        pause();
        
        while (submenu) {
            System.out.println("\n-------- 设备升级管理 --------");
            System.out.println("1. 安装精准导航系统");
            System.out.println("2. 安装自动灌溉系统");
            System.out.println("3. 使用精准导航功能");
            System.out.println("4. 使用自动灌溉功能");
            System.out.println("5. 补充水箱");
            System.out.println("0. 返回主菜单");
            System.out.print("请选择操作 (0-5): ");
            
            int choice = getUserChoice(0, 5);
            switch (choice) {
                case 1:
                    int navId = getIntInput(0, 2, "请选择要安装精准导航系统的设备ID (0-2): ");
                    system.addPrecisionGuidanceSystem(navId);
                    pause();
                    break;
                case 2:
                    int irrId = getIntInput(0, 2, "请选择要安装自动灌溉系统的设备ID (0-2): ");
                    system.addAutoIrrigationSystem(irrId);
                    pause();
                    break;
                case 3:
                    int useNavId = getIntInput(0, 2, "请选择要使用精准导航的设备ID (0-2): ");
                    system.usePrecisionGuidance(useNavId);
                    pause();
                    break;
                case 4:
                    int useIrrId = getIntInput(0, 2, "请选择要使用自动灌溉的设备ID (0-2): ");
                    system.useAutoIrrigation(useIrrId);
                    pause();
                    break;
                case 5:
                    int refillId = getIntInput(0, 2, "请选择要补充水箱的设备ID (0-2): ");
                    system.refillWater(refillId);
                    pause();
                    break;
                case 0:
                    submenu = false;
                    break;
            }
        }
    }
    
    private static void runSimulation() {
        System.out.println("\n【设计模式应用】外观模式：系统提供一个统一的接口");
        System.out.println("  - FarmingSystemFacade类封装了系统所有组件的交互");
        System.out.println("  - 客户端只需通过外观接口与系统交互，无需了解内部实现细节");
        pause();
        
        System.out.println("\n开始运行完整系统模拟...");
        system.simulateOperation();
        System.out.println("模拟完成!");
        pause();
    }
    
    private static void systemStatus() {
        System.out.println("\n-------- 系统状态信息 --------");
        system.showSystemStatus();
        pause();
    }
    
    // 添加暂停功能
    private static void pause() {
        System.out.println("\n按回车键继续...");
        scanner.nextLine();
    }
}